﻿using mds.Common;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;

namespace mds.CMS
{
    /// <summary>
    /// 模板标签管理器,注意此类不支持多线程并发操作，如需要并发操作请将委托方法改造为类内方法,并使用ConvertLabelToContent的三个参数的方法
    /// </summary>
    public class LabelProvider
    {
        private static LabelProvider _instance = new LabelProvider();
        public static LabelProvider Instance
        {
            get
            {
                return _instance;
            }
        }
        public LabelCondition Condition
        {
            set;
            get;
        }
        /// <summary>
        /// key为标签名value为要替换内容
        /// </summary>
        public Dictionary<string, string> StringInfoContents
        {
            set;
            get;
        }
        /// <summary>
        /// key为标签value为要替换内容
        /// </summary>
        public Dictionary<string, DateTime> DatetimeContents
        {
            set;
            get;
        }
        /// <summary>
        /// 此方法中需要对DatetimeContents和StringInfoContents属性赋值
        /// </summary>
        /// <param name="lableCondition"></param>
        public delegate void GetDataFromLableCondition(LabelCondition lableCondition);
        private GetDataFromLableCondition m_GetDataFunction;

        public GetDataFromLableCondition GetDataFunction
        {
            set { m_GetDataFunction = value; }
        }    
        /// <summary>
        /// 将模板转换为静态页的内容
        /// </summary>
        /// <param name="pageTemplate"></param>
        /// <returns></returns>
        public string ConvertToContent(string pageTemplate)
        {
            MatchCollection omcMatchs = Regex.Matches(pageTemplate, GetListLabel(), RegexOptions.IgnoreCase);
            //处理各个{loop...}...{/loop}
            foreach (Match omMatch in omcMatchs)
            {
                pageTemplate = pageTemplate.Replace(omMatch.ToString(), ConvertLoopLable(omMatch));
            }
            return pageTemplate;
        }
        private string ConvertLoopLable(Match omMatch)
        {
            GetLabelCondition(omMatch);
            m_GetDataFunction(Condition);
            return ConvertLabelToContent(GetPartTemplate(omMatch));
        }
        /// <summary>
        /// 简单标签置换
        /// </summary>
        /// <param name="templateContent"></param>
        /// <param name="dicLabel"></param>
        /// <returns></returns>
        internal string GetContent(string templateContent, Dictionary<string, string> dicLabel)
        {
            foreach (var kv in dicLabel)
            {
                templateContent = templateContent.Replace(kv.Key, kv.Value);
            }
            return templateContent;
        }      
        /// <summary>
        /// 复杂标签置换
        /// </summary>
        /// <param name="stringInfoContents"></param>
        /// <param name="datetimeContents"></param>
        /// <param name="pageTemplate"></param>
        /// <returns></returns>
        private string ConvertLabelToContent(string pageTemplate)
        {
            foreach (var kv in DatetimeContents)
            {
                pageTemplate = ConvertDateLable(kv.Value, pageTemplate, kv.Key);

            }
            int showLength;
            foreach (var de in StringInfoContents)
            {
                Match om = Regex.Match(pageTemplate, @"\{\$" + de.Key.ToString() + @"(?:(\})|(?:\[(?<lengthval>\d{1,3})\]\}))", RegexOptions.IgnoreCase);
                if (om.Success)
                {
                    showLength=0;
                    int.TryParse(om.Groups["lengthval"].ToString(),out showLength);
                    if(showLength==0){
                        showLength=de.Value.Length;
                    }
                    pageTemplate = Regex.Replace(pageTemplate, @"\{\$" + de.Key.ToString() + @"((\})|(?:\[+(\d{1,3})+\]\}))", StringOperate.SqlText(de.Value, showLength), RegexOptions.IgnoreCase);
                }
            }
            return pageTemplate;
        }
        public string ConvertLabelToContent(string pageTemplate, Dictionary<string, string> stringInfoContents, Dictionary<string, DateTime> datetimeContents)
        {
            foreach (var kv in datetimeContents)
            {
                pageTemplate = ConvertDateLable(kv.Value, pageTemplate, kv.Key);

            }
            int showLength;
            foreach (var de in stringInfoContents)
            {
                Match om = Regex.Match(pageTemplate, @"\{\$" + de.Key.ToString() + @"(?:(\})|(?:\[(?<lengthval>\d{1,3})\]\}))", RegexOptions.IgnoreCase);
                if (om.Success)
                {
                    showLength = 0;
                    int.TryParse(om.Groups["lengthval"].ToString(), out showLength);
                    if (showLength == 0)
                    {
                        showLength = de.Value.Length;
                    }
                    pageTemplate = Regex.Replace(pageTemplate, @"\{\$" + de.Key.ToString() + @"((\})|(?:\[+(\d{1,3})+\]\}))", StringOperate.SqlText(de.Value, showLength), RegexOptions.IgnoreCase);
                }
            }
            return pageTemplate;
        }
        public LabelCondition GetLabelCondition(Match LoopLableMatch)
        {
            
            LabelCondition condition = new LabelCondition() { 
                 Condition = LoopLableMatch.Groups["cval"].ToString(),
                 LoopNum = int.Parse(LoopLableMatch.Groups["lnval"].ToString()),
                 InfoType = int.Parse(LoopLableMatch.Groups["nidval"].ToString()),
                 Sort = LoopLableMatch.Groups["sortval"].ToString(),
                 Start = int.Parse(LoopLableMatch.Groups["startval"].ToString())
            };
            Condition = condition;
            return condition;
        }
        private string GetPartTemplate(Match LoopLableMatch)
        {
            return LoopLableMatch.Groups["htmlval"].ToString();
        }
        private string ConvertDateLable(DateTime dateTime, string pageTemplate, string timeLabel)
        {
            string regex = @"\{\$" + timeLabel + @"\[([\s\S]*?)\]\}";
            Match m = Regex.Match(pageTemplate, regex, RegexOptions.IgnoreCase);
            if (m.Success)
            {
                string strTime = m.Result("$1");
                strTime = strTime.Replace("yyyy", dateTime.Year.ToString());
                strTime = strTime.Replace("mm", dateTime.Month.ToString());
                strTime = strTime.Replace("dd", dateTime.Day.ToString());
                pageTemplate = pageTemplate.Replace(m.ToString(), strTime);
            }
            else
            {
                pageTemplate = pageTemplate.Replace("{$" + timeLabel + "}", dateTime.ToShortDateString());
            }
            return pageTemplate;
        }
        /// <summary>
        /// 获取列表标签
        /// </summary>
        /// <returns></returns>
        private string GetListLabel()
        {
            string pattern1 = "infoId=\"" + @"(?<nidval>[\d{1,3},]+)+?" + "\"";
            string pattern2 = "start=\"" + @"(?<startval>\d{1,2})" + "\"";
            string pattern3 = "loopnum=\"" + @"(?<lnval>\d{1,3})" + "\"";
            string pattern4 = "condition=\"" + @"(?<cval>[\S\s]*?)" + "\"";
            string pattern5 = "sort=\"" + @"(?<sortval>[\S\s]*?)" + "\"";
            string pattern6 = "infoType=\"" + @"(?<ntval>[\d{1,3},]+)+?" + "\"";
            string pattern = @"\{nloop(\s+(" + pattern1 + "|" + pattern2 + "|" + pattern3 + "|" + pattern4 + "|" + pattern5 + "|" + pattern6 + @"))+\}(?<htmlval>[\s\S]*?)\{/nloop\}";
            return pattern;
        }
    }
}
